package com.qsl.file;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:
 * @Author: 博客园@青石路
 * @CreateDate: 2022/7/1 8:58
 **/
public class FileCompare {

    public static void main(String[] args) throws IOException {
        boolean flag = compare("D:\\恒生聚源\\IDG 数据迁移\\第十一批迁移\\测试不一致文件再生成\\dbf\\目录2\\方正富邦基金恒生估值含央行报送\\20221109\\tb_trusteeship_20221109.dbf",
                "D:\\恒生聚源\\IDG 数据迁移\\第十一批迁移\\测试不一致文件再生成\\dbf\\目录1\\产品包1805_20221109\\20221109\\tb_trusteeship_20221109.dbf");
        System.out.println(flag);
    }

    public static boolean compare(String filePath1, String filePath2) throws IOException {
        char[] b1 = IOUtils.toCharArray(new FileInputStream(new File(filePath1)), Charset.defaultCharset());
        char[] b2 = IOUtils.toCharArray(new FileInputStream(new File(filePath2)), Charset.defaultCharset());
        if (b1.length != b2.length) {
            System.out.println(b1.length);
            System.out.println(b2.length);
            // 文件不一致
            return false;
        }
        Map<String, Integer> m1 = getLineMd5(b1);
        Map<String, Integer> m2 = getLineMd5(b2);
        for (Map.Entry<String, Integer> entry : m1.entrySet()) {
            String key = entry.getKey();
            Integer val = entry.getValue();
            if ((!m2.containsKey(key)) || m2.get(key).intValue() != val.intValue()) {
                // 不一致
                return false;
            }
            m2.remove(key);

        }
        if (m2.size() != 0) {
            return false;
        }
        return true;
    }

    public static Map<String, Integer> getLineMd5(char[] b1) {
        Map<String, Integer> m1 = new HashMap<>();
        MessageDigest digest = DigestUtils.getMd5Digest();
        boolean flag = false;
        for (int i = 0; i < b1.length; i++) {
            digest.update(charToByte(b1[i]));
            flag = true;
            if (b1[i] == '\r') {
                i++;
                if (b1[i] == '\n') {
                    digest.update(charToByte(b1[i]));
                } else {
                    i--;
                }
                String lineMd5 = Hex.encodeHexString(digest.digest());
                m1.put(lineMd5, MapUtils.getInteger(m1, lineMd5, 0) + 1);
//				m1.add(lineMd5);
                digest = DigestUtils.getMd5Digest();
                flag = false;
            }
            if (b1[i] == '\n') {
                String lineMd5 = Hex.encodeHexString(digest.digest());
                m1.put(lineMd5, MapUtils.getInteger(m1, lineMd5, 0) + 1);
//				m1.add(lineMd5);
                digest = DigestUtils.getMd5Digest();
                flag = false;
            }
        }
        if (flag) {
            String lineMd5 = Hex.encodeHexString(digest.digest());
            m1.put(lineMd5, MapUtils.getInteger(m1, lineMd5, 0) + 1);
//			m1.add(lineMd5);
        }
        return m1;
    }

    public static byte[] charToByte(char c) {

        byte[] b = new byte[2];

        b[0] = (byte) ((c & 0xFF00) >> 8); // 0xff00=1111 1111 0000 0000

        b[1] = (byte) (c & 0xFF); // 0xff,=1111 1111

        return b;

    }
}
